/**
 * EpochHandler.java
 * ************************** 
 * @date Mar 31, 2011
 * @author Michele Tamburini
 * 
 * **************************
 */
package gossipServices.aggregation;

import messages.Message;
import gossipServices.basic.nodeDescriptors.NodeDescriptor;
import gossipServices.gossipMessages.AggregationMessage;

/**
 * Description: 
 * Class used by the Aggregation protocol in order
 * to provide the epochs and cycles handling.
 * Each time two nodes succeed in perform an exchange
 * of their estimation values, 
 * a cycle for in the Aggregation protocol is elapsed. 
 * The overall run of the protocol is partitioned in epochs.
 * At the beginning of an epoch each node must 
 * initialize all its variables (especially the estimation
 * values)  
 * 
 */
public interface EpochHandler {
	
	/**
	 * 
	 * Description: 
	 * Values returned by the function: 
	 * 			checkEpochs()
	 * which must be called from a node after a receive().
	 *  
	 * exchange: means that the two nodes can exchange their 
	 * 			estimation values because both running in the 
	 * 			same epoch;
	 * sendCorrectEpoch: means that the received message belongs
	 * 			to an older epoch and that node need to be 
	 * 			corrected to the current one;
	 * updateCurrentEpoch: means that the incoming message is an 
	 * 			answer containing instructions to correctly set 
	 * 			the current node epoch and remaining cycles.
	 */
	public static enum EpochCheckReturn {exchange, sendCorrectEpoch, updateCurrentEpoch};

	/**
	 * Increment the cycles of the Aggregation protocol.
	 * It must be called after a successful exchange 
	 * between two nodes.
	 */
	public void elapsedCycle() throws AggregationRestartException;

	/**
	 * It returns the current epoch.
	 * @return epoch:int
	 */
	public int getEpoch();
	
	/**
	 * Set the current epoch to the value of newEpoch
	 * @param newEpoch:int
	 */
	public void setEpoch(int newEpoch);

	/**
	 * Returns the number of remaining cycles 
	 * before the next epoch occurs.
	 * @return remainingCycles:int
	 */
	public int getRemainingCycles();

	/**
	 * Returns the number of elapsed cycles from 
	 * the beginning of the current epoch.
	 * @return elapsedCycles:int
	 */
	public int getElapsedCycles();
	
	/**
	 * This function must be called generally after a receive()
	 * from another node.
	 * It compares the epochs of the incoming message and the
	 * local node and returns the action to be performed as 
	 * listed in the enumeration EpochCheckReturn. 
	 * 
	 * @param incomingMsg:AggregationMessage
	 * @param localEpochHandler:EpochHandler
	 * @return action:EpochCheckReturn
	 */
	public EpochCheckReturn checkEpochs(AggregationMessage incomingMsg, 
			EpochHandler localEpochHandler);


	/**
	 * Update the local node epoch to the one 
	 * that the input message carries.
	 * @param msgq:AggregationMessage
	 */
	public void updateCurrentEpoch(AggregationMessage msgq) throws AggregationRestartException;

	/**
	 * Returns a correction message for the target node 'dest'.
	 * The correction message generally carries the
	 * current epoch and the number of remaining cycles
	 * until the next epoch.
	 * @param me
	 * @param dest
	 * @return
	 */
	public Message composeCorrectionMessage(NodeDescriptor me,
			NodeDescriptor dest, Object gossipThread);

	/**
	 * @return
	 */
	int getPrecedingElapsedCycles();

	/**
	 * @return
	 */
	int getPrecedingEpoch(); 

}
